/*
 * @Author: Troubadour 2276791354@qq.com
 * @Date: 2024-08-10 23:29:50
 * @LastEditors: Troubadour 2276791354@qq.com
 * @LastEditTime: 2024-08-11 01:23:25
 * @Version:
 * @Description:
 */

/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  Include file                                                                       -
--------------------------------------------------------------------------------------------------------------------------------------*/
#include "KeySw.h"

/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  Internal macro                                                                     -
--------------------------------------------------------------------------------------------------------------------------------------*/


#define KEY_SW_FILTER_CNT_MIN       (50)
#define KEY_SW_FILTER_CNT_MED       (250)
#define KEY_SW_FILTER_CNT_MAX       (500)
/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  Internal enum                                                                      -
--------------------------------------------------------------------------------------------------------------------------------------*/


/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  Internal structure                                                                 -
--------------------------------------------------------------------------------------------------------------------------------------*/


/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  Internal function                                                                  -
--------------------------------------------------------------------------------------------------------------------------------------*/


/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  Internal variables                                                                 -
--------------------------------------------------------------------------------------------------------------------------------------*/

KeySw_TypeDef KeySw_List[] = {
    {KEYSW_UP_ID, KEY_UP_GPIO_Port, KEY_UP_Pin, 0, 0, KEY_SW_FILTER_CNT_MED},
    {KEYSW_DOWN_ID, KEY_DOWN_GPIO_Port, KEY_DOWN_Pin, 0, 0, KEY_SW_FILTER_CNT_MED},
    {KEYSW_TOUCH_ID, KEY_TOUCH_GPIO_Port, KEY_TOUCH_Pin, 0, 0, KEY_SW_FILTER_CNT_MED}
};
/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  External variables                                                                 -
--------------------------------------------------------------------------------------------------------------------------------------*/


/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  Function body                                                                      -
--------------------------------------------------------------------------------------------------------------------------------------*/

/**
 * @function: KeySw_GetPin
 * @brief This function is used to get the state of the key switch.
 * @param {KeySw_ID_TypeDef} Pin_ID: The ID of the key switch.
 * @return {uint8_t} The state of the key switch. 0 is low level, 1 is high level, 2 is error.
 */
uint8_t KeySw_GetPin(KeySw_ID_TypeDef Pin_ID)
{
    for (uint16_t i = 0; i < KEYSW_STATE_MAX; i++)
    {
        if (i == Pin_ID)
        {
            return KeySw_List[i].state;
        }
    }
    return 2;
}

/**
 * @function: KeySw_GetTrigger
 * @brief This function is used to get the trigger of the key switch.
 * @param {KeySw_ID_TypeDef} *Pin_ID: If the trigger is triggered, the ID of the key switch will be written to this address.
 * @param {uint8_t} clear_trigger: 0 is not clear, 1 is clear.
 * @return {uint8_t} 0 is not triggered, 1 is triggered, 2 is error.
 */
uint8_t KeySw_GetTrigger(KeySw_ID_TypeDef *Pin_ID, uint8_t clear_trigger)
{
    if (Pin_ID == NULL) return 2;

    for (uint16_t i = 0; i < KEYSW_STATE_MAX; i++)
    {
        if (KeySw_List[i].trigger == 1)
        {
            if (clear_trigger == 1)
            {
                KeySw_List[i].trigger = 0;
            }
            *Pin_ID = KeySw_List[i].id;
            return 1;
        }
    }
    return 0;
}

/**
 * @function: KeySw_Scanf_Task
 * @brief This function is used to scan the key switch.
 * @return {void}
 */
void KeySw_Scanf_Task(void)
{
    uint8_t pin_state = 0;

    for (uint16_t i = 0; i < KEYSW_STATE_MAX; i++)
    {
        pin_state = KEYSW_Read_Pin(KeySw_List[i].GPIOx, KeySw_List[i].GPIO_Pin);
        if (pin_state != KeySw_List[i].state)
        {
            KeySw_List[i].filter_cnt += KEYSW_SCANF_PERIOD_MS;
            if (KeySw_List[i].filter_cnt >= KeySw_List[i].filter_threshold)
            {
                KeySw_List[i].state = pin_state;
                KeySw_List[i].filter_cnt = 0;
                KeySw_List[i].trigger = 1;
            }
        }
        else
        {
            (KeySw_List[i].filter_cnt <= KEYSW_SCANF_PERIOD_MS) ? (0) : (KeySw_List[i].filter_cnt -= KEYSW_SCANF_PERIOD_MS);
        }
    }
}



